# Author:  wuxianfeng
# Company: songqin
# File:    basePage.py
# Date:    22-9-21
# Time:    下午 8:52
import os

import allure
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from common.commin.comm_driver import CommDriver
from common.yaml.read_yaml import get_yaml_data1
from config.conf import Test_data, Fail_Picture
from config.env import Env
from common.log.log import log


class BasePage:
    """
    页面基类
        - 获取浏览器实例
        - 打开网页
        - 定位元素
        - 输入文本
        - 点击元素
        ...
    """

    def __init__(self):
        """
        初始化方法
            1. 获取浏览器实例
        """
        self.driver = CommDriver().get_driver()
        # 优化1. 把每个页面要获取到的元素信息(元素名:定位器)得到
        #   缺陷：  loginpage拿到了所有页面的元素
        # self.locators = get_yaml_data(PollyPath.configs_path / 'allelements.yaml')
        # 优化2： 每个页面拿自己的
        # 缺陷 用的时候  self.locators['username_input'] 挺麻烦的
        # get_yaml_data1(os.path.join(Test_data, 'yk_allelements.yaml'))
        self.locators = get_yaml_data1(os.path.join(Test_data, 'yk_allelements.yaml'))[self.__class__.__name__]
        # print(self.locators)
        # 优化3： 把k-v 成为实例的属性名-属性值
        for element_name, locator in self.locators.items():
            setattr(self, element_name, locator)  # login_button属性的值是['id', 'btnLogin']

    def open_url(self, url):
        """
        Note: 在本项目是多余的，但写在这里，可以做二次封装，扩展get的功能，
        比如说selenium的get是对协议有要求的（file:///），就可以扩展
        Args:
            url: 要打开的浏览器的网址

        Returns:  None

        """
        self.driver.get(url)

    @allure.step("退出浏览器操作：")
    def driver_quit(self):
        self.driver.quit()

    def driver_close(self):
        self.driver.close()

    def get_elelment_old(self, locator):
        """
        获取元素
        Args:
            locator:  元素的定位器
                eg. 'id','ls_username'

        Returns: WebElement

        """
        import warnings
        warnings.warn('this method has been deprecated!please use input instead.', DeprecationWarning)

        return self.driver.find_element(*locator)

    @allure.step("获取元素属性：")
    def get_elelment(self,
                     locator,
                     timeout=Env.TIMEOUT,
                     poll_frequency=Env.POLL_FREQUENCY,
                     desc=None,
                     elements=False):
        """

        Args:
            locator:  元素的定位器
                eg. 'id','ls_username'
            timeout: 显式等待超时时间
            poll_frequency: 轮训频率
            elements： 是否定位多个元素-->此时的返回是个 list
        Returns: 元素

        """
        # PO1:The public methods represent the services that the page offers
        try:
            if not elements:
                return WebDriverWait(self.driver, timeout, poll_frequency). \
                    until(EC.visibility_of_element_located(locator))
            else:
                return WebDriverWait(self.driver, timeout, poll_frequency). \
                    until(EC.visibility_of_all_elements_located(locator))
        except:
            from time import strftime  # arrow
            import os
            curtime = strftime('%Y%m%d%H%M%S')
            # {os.sep} 能适配操作系统
            self.driver.save_screenshot(f'{Fail_Picture}{os.sep}{desc}.png')
            # from utils.handle_loguru import log
            # 上面的这个导入 建议放到  except中； 不要放到最顶层？
            # 如果放到顶层，没有日志也会产生一个问卷
            log.error(f'{desc}元素找不到')
            return False  # 可以借用这个定位同时判断元素是否存在

    def input_text_old(self, locator, text):
        """

        Args:
            locator: 待输入文本的元素的定位器
            text:  待输入的文本

        Returns: None
        Note   send_keys 默认是 追加输入
        """
        import warnings
        warnings.warn('this method has been deprecated!please use input instead.', DeprecationWarning)
        self.get_elelment(locator).send_keys(text)

    @allure.step("输入内容：")
    def input_text(self, locator, text, append=False, desc=None):
        """

        Args:
            locator: 待输入文本的元素的定位器
            text:  待输入的文本
            append: 是否要追加输入，默认不追加(False)

        Returns: None
        """
        if append:
            self.get_elelment(locator, desc=desc).send_keys(text)
        else:
            self.get_elelment(locator, desc=desc).clear()
            self.get_elelment(locator, desc=desc).send_keys(text)
        # PO6: Different results for the same action are modelled as different methods
        # 没有遵循PO6

    @allure.step("点击元素")
    def click_element(self, locator, desc=None):
        """
        点击指定的元素
        Args:
            locator: 待点击元素的定位器

        Returns: None

        """
        self.get_elelment(locator, desc=desc).click()

    @allure.step("获取元素文本")
    def get_element_text(self, locator, desc=None):
        print(locator)
        """
        获取指定元素的文本
        Args:
            locator: 指定元素的定位器

        Returns: 指定的元素的文本

        """
        return self.get_elelment(locator, desc=desc).text

    @allure.step("获取所有元素文本")
    def get_elements_text(self, locator, desc=None):
        allelements = self.get_elelment(locator, elements=True, desc=desc)  # list
        return [element.text for element in allelements]

    @allure.step("获取元素属性的值")
    def new_get_elelment_attribute(self, locator, desc=None):
        """
        获取指定元素的文本
        locator: 指定元素的定位器
        Returns: 指定的元素的文本
        """
        return self.get_elelment(locator, desc=desc).get_attribute("textContent")


if __name__ == '__main__':
    # import os
    # print(Test_data)
    # print(get_yaml_data1(os.path.join(Test_data,'yk_allelements.yaml'))['LoginPage'])
    test_flag = 2
    if test_flag == 2:
        from po.yk.ht.logingPage import LoginPage

        test_loginpage = LoginPage()
        test_loginpage.open_polly_loginpage()
        test_loginpage.login_polly('admin', '123456', '123456')
        # test_loginpage.get_elelment(('id','username'),desc='用户名')
    if test_flag == 1:
        # 删除线的演示
        BasePage().input_text_old()
